package Triangulation.minimalityMetrics;

import static tools.Tool.quadIsConvex;
import datatypes.Edge;
import datatypes.Triangle;

public class UniformAnglesMetric extends AbstractMinimalityMetric
implements MinimumTriangleSumMetric {
	
	private double ratioForTriangles(Triangle t1, Triangle t2) {
		// summing up the ratios of both triangles:
		double ratio = getTriangleWeight(t1) + getTriangleWeight(t2);
//		System.out.println(ratio);
		return ratio;
	}

	@Override
	public double getTriangleWeight(Triangle t) {
		double minAngle = t.getMinAngle();
		double maxAngle = t.getMaxAngle();
		return maxAngle / minAngle;
	}

	@Override
	public boolean edgeIsLocallyMinimal(Edge sharedEdge, Triangle t1, Triangle t2) {
		if ( ! quadIsConvex(t1, t2, sharedEdge)) {
			// If quad is NOT convex, then sharedEdge is locally minimal.
			// See "A Large Subgraph of the Minimum Weight Triangulation" 
			// p.291, 1.3
			return true;
		}
		double ratioExistingQuad = ratioForTriangles(t1, t2);
		
		Edge perpendicular = new Edge(t1.getVertexNotOnEdge(sharedEdge), t2.getVertexNotOnEdge(sharedEdge));
		Edge e2t1 = new Edge(perpendicular.getVertex1(), sharedEdge.getVertex1());
		Edge e3t1 = new Edge(perpendicular.getVertex2(), sharedEdge.getVertex1());
		Edge e2t2 = new Edge(perpendicular.getVertex1(), sharedEdge.getVertex2());
		Edge e3t2 = new Edge(perpendicular.getVertex2(), sharedEdge.getVertex2());
		
		try {
			t1 = new Triangle(perpendicular, e2t1, e3t1, false);
			t2 = new Triangle(perpendicular, e2t2, e3t2, false);
		} catch (Exception e) {
			e.printStackTrace();
		}
//		System.out.println(t1 + "   /   " + t2);
		double ratioFlippedQuad = ratioForTriangles(t1, t2);
		return ratioExistingQuad <= ratioFlippedQuad;
	}

	@Override
	public double getAngleForDiamondProperty() {
		// Diamond property not known to be applicable.
		return -1;
	}

	@Override
	public String getName() {
		return "balanced angles";
	}

}
